//
// Created by Administrator on 2020/10/15.
//

#include "../include/cellmApi.h"
#include "cellFsm.h"

int32_t RAN_L3_CELLM_Init(void)
{
    int32_t rc;

    rc = RAN_L3_CELL_SM_Init();
    IF_RETURN(!=, O5G_RC_OK, rc, O5G_RC_ER, "RAN_L3_CELLM_Init() RAN_L3_CELL_SM_Init() error!\n");

    return O5G_RC_OK;
}

int32_t RAN_L3_CELLM_Final(void)
{
    int32_t rc;

    rc = RAN_L3_CELL_SM_Final();
    IF_RETURN(!=, O5G_RC_OK, rc, O5G_RC_ER, "RAN_L3_CELLM_Final() RAN_L3_CELL_SM_Final() error!\n");

    return O5G_RC_OK;
}

void RAN_L3_CELLM_IndProcess(S_OsSelectInd *pIndMsg)
{
    switch (pIndMsg->ind)
    {
    case RAN_L3_INTRA_IND_MSG_CELL_FSM_EVT:
        RAN_L3_CELL_SM_IndProcess(pIndMsg);
        break;
    default:
        break;
    }
}

void RAN_L3_CELLM_MsgProcess(S_RanCommMsgHdr *pCommMsgHdr)
{
    uint32_t nbIdx;
    uint32_t cellIdx;
    S_RanL3CellInst *pCellInst;
    S_FsmEventContext evtCtxt;
    S_OsSelectInd indMsg;

    switch (pCommMsgHdr->type)
    {
    case RAN_L1_API_MSG_PARAMS_RSP:
        CSP_LOG_INF(RAN_MD_L3_COMM, "RAN_L3_CELLM_MsgProcess() recv RAN_L1_API_MSG_PARAMS_RSP\n");

        nbIdx = ((S_RanL1ApiMsgParamsRsp *)pCommMsgHdr)->nbIdx;
        cellIdx = ((S_RanL1ApiMsgParamsRsp *)pCommMsgHdr)->cellIdx;
        pCellInst = &gpRanL3Context->nbInst[nbIdx].cellInst[cellIdx];

        evtCtxt.event = RAN_L3_CELL_SM_EVENT_RECV_L1_PARAMS_RSP;
        evtCtxt.context = pCellInst;
        FixRB_Put(gpRanL3Context->cellFsmEvtQue, &evtCtxt, sizeof(evtCtxt));
        break;
    case RAN_L1_API_MSG_CONFIG_RSP:
        CSP_LOG_INF(RAN_MD_L3_COMM, "RAN_L3_CELLM_MsgProcess() recv RAN_L1_API_MSG_CONFIG_RSP\n");

        nbIdx = ((S_RanL1ApiMsgConfigRsp *)pCommMsgHdr)->nbIdx;
        cellIdx = ((S_RanL1ApiMsgConfigRsp *)pCommMsgHdr)->cellIdx;
        pCellInst = &gpRanL3Context->nbInst[nbIdx].cellInst[cellIdx];

        evtCtxt.event = RAN_L3_CELL_SM_EVENT_RECV_L1_CONFIG_RSP;
        evtCtxt.context = pCellInst;
        FixRB_Put(gpRanL3Context->cellFsmEvtQue, &evtCtxt, sizeof(evtCtxt));
        break;
    case RAN_L2_L3_MSG_CONFIG_RSP:
        CSP_LOG_INF(RAN_MD_L3_COMM, "RAN_L3_CELLM_MsgProcess() recv RAN_L2_L3_MSG_CONFIG_RSP\n");

        nbIdx = ((S_RanL2L3MsgConfigRsp *)pCommMsgHdr)->nbIdx;
        cellIdx = ((S_RanL2L3MsgConfigRsp *)pCommMsgHdr)->cellIdx;
        pCellInst = &gpRanL3Context->nbInst[nbIdx].cellInst[cellIdx];

        evtCtxt.event = RAN_L3_CELL_SM_EVENT_RECV_L2_CONFIG_RSP;
        evtCtxt.context = pCellInst;
        FixRB_Put(gpRanL3Context->cellFsmEvtQue, &evtCtxt, sizeof(evtCtxt));
        break;
    case RAN_L1_API_MSG_START_RSP:
        CSP_LOG_INF(RAN_MD_L3_COMM, "RAN_L3_CELLM_MsgProcess() recv RAN_L1_API_MSG_START_RSP\n");

        nbIdx = ((S_RanL1ApiMsgStartRsp *)pCommMsgHdr)->nbIdx;
        cellIdx = ((S_RanL1ApiMsgStartRsp *)pCommMsgHdr)->cellIdx;
        pCellInst = &gpRanL3Context->nbInst[nbIdx].cellInst[cellIdx];

        evtCtxt.event = RAN_L3_CELL_SM_EVENT_RECV_L1_START_RSP;
        evtCtxt.context = pCellInst;
        FixRB_Put(gpRanL3Context->cellFsmEvtQue, &evtCtxt, sizeof(evtCtxt));
        break;
    case RAN_L2_L3_MSG_START_RSP:
        CSP_LOG_INF(RAN_MD_L3_COMM, "RAN_L3_CELLM_MsgProcess() recv RAN_L2_L3_MSG_START_RSP\n");

        nbIdx = ((S_RanL2L3MsgStartRsp *)pCommMsgHdr)->nbIdx;
        cellIdx = ((S_RanL2L3MsgStartRsp *)pCommMsgHdr)->cellIdx;
        pCellInst = &gpRanL3Context->nbInst[nbIdx].cellInst[cellIdx];

        evtCtxt.event = RAN_L3_CELL_SM_EVENT_RECV_L2_START_RSP;
        evtCtxt.context = pCellInst;
        FixRB_Put(gpRanL3Context->cellFsmEvtQue, &evtCtxt, sizeof(evtCtxt));
        break;
    case RAN_L3_L2_MSG_MIB_TX_RSP:
        CSP_LOG_INF(RAN_MD_L3_COMM, "RAN_L3_CELLM_MsgProcess() recv RAN_L3_L2_MSG_MIB_TX_RSP\n");

        nbIdx = ((S_RanL2L3MsgMibTxRsp *)pCommMsgHdr)->nbIdx;
        cellIdx = ((S_RanL2L3MsgMibTxRsp *)pCommMsgHdr)->cellIdx;
        pCellInst = &gpRanL3Context->nbInst[nbIdx].cellInst[cellIdx];

        evtCtxt.event = RAN_L3_CELL_SM_EVENT_RECV_L2_MIB_TX_RSP;
        evtCtxt.context = pCellInst;
        FixRB_Put(gpRanL3Context->cellFsmEvtQue, &evtCtxt, sizeof(evtCtxt));
        break;
    default:
        CSP_LOG_WRN(RAN_MD_L3_COMM, "RAN_L3_CELLM_MsgProcess() recv unsupport msg[%#x]\n", pCommMsgHdr->type);
        break;
    }

    indMsg.ind = RAN_L3_INTRA_IND_MSG_CELL_FSM_EVT;
    OS_SelectSend(&gpRanL3Context->selector, &indMsg);
}

void RAN_L3_CELLM_PrdProcess(void)
{
    uint32_t nbLoop;
    uint32_t cellLoop;
    uint32_t needSendInd;
    S_RanL3NbInst *pNbInst;
    S_RanL3CellInst *pCellInst;
    S_FsmEventContext evtCtxt;
    S_OsSelectInd indMsg;

    needSendInd = FALSE;

    if (0 != gpRanL3Context->tick10ms % 10)
    {
        return;
    }

    for (nbLoop = 0; nbLoop < gpRanL3Context->nbNum; nbLoop++)
    {
        pNbInst = &gpRanL3Context->nbInst[nbLoop];
        IF_CONTINUE(==, FALSE, pNbInst->inUse, NO_LOG_MESSAGE);

        if (RAN_L3_NB_SM_STATE_NGAP_SETUP_SUCC != FSM_INST_GetState(pNbInst->nbSmInst))
        {
            continue;
        }
        for (cellLoop = 0; cellLoop < RAN_CELL_NUM_MAX; cellLoop++)
        {
            pCellInst = &pNbInst->cellInst[cellLoop];
            IF_CONTINUE(==, FALSE, pCellInst->inUse, NO_LOG_MESSAGE);

            if (RAN_L3_CELL_SM_STATE_INIT != FSM_INST_GetState(pCellInst->cellSmInst))
            {
                continue;
            }
            evtCtxt.event = RAN_L3_CELL_SM_EVENT_CELL_SETUP_TRIGGER;
            evtCtxt.context = pCellInst;

            FixRB_Put(gpRanL3Context->cellFsmEvtQue, &evtCtxt, sizeof(evtCtxt));
            needSendInd = TRUE;
        }
    }

    if (needSendInd)
    {
        indMsg.ind = RAN_L3_INTRA_IND_MSG_CELL_FSM_EVT;
        OS_SelectSend(&gpRanL3Context->selector, &indMsg);
    }
}

